package dao

import (
	"context"
	"errors"
	"go-learn/global"
	demo2 "go-learn/model/pb"
	"go-learn/model/request"
	"go.mongodb.org/mongo-driver/bson"
)

/*
	添加一条文档
*/
func InsertOne(collection string, user demo2.User) error {
	c := global.GvaMongodb.Collection(collection)
	_, err := c.InsertOne(context.TODO(), user)
	return err
}

/*
	添加多条文档
*/
func InsertMany(collection string, users []demo2.User) error {
	c := global.GvaMongodb.Collection(collection)
	var documents []interface{}
	for _, user := range users {
		documents = append(documents, user)
	}
	var _, err = c.InsertMany(context.TODO(), documents)
	return err
}

/*
	根据id更新文档
*/
func UpdateById(collection string, user demo2.User) error {
	c := global.GvaMongodb.Collection(collection)
	if user.Id == 0 {
		return errors.New("id format error or does not exist!")
	}
	_, err := c.UpdateByID(context.TODO(), user.Id, bson.M{"$set": user})
	return err
}

/*
	更新多条文档
*/
func UpdateMany(collection string, query request.UserQuery, updateMap map[string]interface{}) error {
	c := global.GvaMongodb.Collection(collection)
	filter := bson.M{}
	if query.Age != 0 {
		filter["age"] = query.Age
	}
	if query.Name != "" {
		filter["name"] = query.Name
	}
	if query.Hobby != "" {
		filter["hobby"] = query.Hobby
	}
	if query.Package != nil {
		for key, value := range query.Package {
			key = "package." + key
			filter[key] = value
		}
	}
	update := bson.M{}
	for key, value := range updateMap {
		update[key] = value
	}
	_, err := c.UpdateMany(context.TODO(), filter, bson.M{"$set": update})
	return err
}

/*
	根据id查找文档
*/
func FindById(collection string, query request.UserQuery, res *demo2.User) error {
	c := global.GvaMongodb.Collection(collection)
	filter := bson.M{}
	if query.Id != "" {
		filter["_id"] = query.Id
	} else {
		return errors.New("id format error or does not exist!")
	}
	err := c.FindOne(context.TODO(), filter).Decode(res)
	return err
}

/*
	查找多条文档
*/
func FindMany(collection string, query request.UserQuery, res *[]demo2.User) error {
	c := global.GvaMongodb.Collection(collection)
	filter := bson.M{}
	if query.Age != 0 {
		filter["age"] = query.Age
		/*
			如果需要添加逻辑运算符则如下格式：
			filter["age"] = bson.M{"$gt": query.Age}
		*/
	}
	if query.Name != "" {
		filter["name"] = query.Name
	}
	if query.Hobby != "" {
		filter["hobby"] = query.Hobby
	}
	if query.Package != nil {
		for key, value := range query.Package {
			key = "package." + key
			filter[key] = value
		}
	}
	cursor, err := c.Find(context.TODO(), filter)
	if err != nil {
		return err
	}
	/*
		返回一个游标值，遍历这个游标获取文档，记得使用后关闭
		注意：Find在err时返回的游标为nil，此时是不需要close的，需要注意err判断和defer的顺序，防止不必要的操作
	*/
	defer cursor.Close(context.TODO())
	for cursor.Next(context.TODO()) {
		var doc demo2.User
		err := cursor.Decode(&doc)
		if err != nil {
			return err
		}
		*res = append(*res, doc)
	}
	return nil
}

/*
	删除一条文档
*/
func DeleteById(collection, id string) error {
	c := global.GvaMongodb.Collection(collection)
	_, err := c.DeleteOne(context.TODO(), bson.M{"_id": id})
	return err
}

/*
	删除多条文档
*/
func DeleteMany(collection string, query request.UserQuery) error {
	c := global.GvaMongodb.Collection(collection)
	filter := bson.M{}
	if query.Age != 0 {
		filter["age"] = query.Age
	}
	if query.Name != "" {
		filter["name"] = query.Name
	}
	if query.Hobby != "" {
		filter["hobby"] = query.Hobby
	}
	if query.Package != nil {
		for key, value := range query.Package {
			key = "package." + key
			filter[key] = value
		}
	}
	_, err := c.DeleteMany(context.TODO(), filter)
	return err
}
